fix: restore OAuth token expiry across process restarts - #3248
Conversation
|
Thanks for the contribution. This repository only keeps pull requests open when they're linked to an issue that a maintainer has assigned to the author — CONTRIBUTING.md explains why and how we work. This PR has been closed for now because its description doesn't yet link an open issue in this repository (with If there isn't an issue for this yet, please open one — a clear description of the problem is genuinely the most useful thing for us. Then add There's no need to open a new PR — this one will be reopened. While it's closed, please push any updates as new commits rather than force-pushing, since GitHub can't reopen a PR whose branch has been rewritten. Maintainers: reopening this PR, removing the |
Problem
OAuthClientProvider._initialize(and the client-credentials providers) reloadscurrent_tokensfrom storage but never restorestoken_expiry_time. The persistedOAuthTokenonly carries the relativeexpires_in, so on a fresh processis_token_valid()returnsTruefor an already-expired access token — a stale Bearer is sent and a 401 round-trip is wasted before re-authentication (mcp2cli issues #50, #57).Fix
Persist the absolute expiry and restore it on init:
expires_at: float | NonetoOAuthToken(absolute unix timestamp), with a doc comment explaining the mcp2cli reproduction that motivated it._handle_token_response,_handle_refresh_response).OAuthContext.restore_token_expiry()and call it from all three_initializemethods (base,ClientCredentialsOAuthProvider,PrivateKeyJwtOAuthProvider).Backwards compatible:
expires_atdefaults toNone; existing stored tokens simply re-auth once, then persist the absolute expiry going forward.Test
test_init_restores_expired_token_expiry— fails onmain(expired token reported valid), passes with the fix. 210 auth tests pass, ruff + pyright clean.